package leetcode.pre50;

/**
 * 给出一个 32 位的有符号整数，你需要将这个整数中每位上的数字进行反转。
 * <p>
 * 示例 1:
 * <p>
 * 输入: 123
 * 输出: 321
 *  示例 2:
 * <p>
 * 输入: -123
 * 输出: -321
 * 示例 3:
 * <p>
 * 输入: 120
 * 输出: 21
 * 注意:
 * <p>
 * 假设我们的环境只能存储得下 32 位的有符号整数，则其数值范围为 [−231,  231 − 1]。
 * <p>
 * 请根据这个假设，如果反转后整数溢出那么就返回 0。
 *
 * @date 2020/3/8 15:45
 */
public class Code07_ReverseInteger {

    /**
     * 注意：  被除数/除数 = 商 .. 余数     商和余数的符号要和 被除数保持一致
     * 如 -123/10 = -12 ..... -3  而不能是 -13.....7
     * <p>
     * -2147483648 , 2147483647
     */
    private static int reverse(int x) {
        int res = 0;
        //正负数
        boolean positive = x >= 0;
        // 123 --> 321
        // -123 --> -321
        while (x != 0) {
            //和被除数保持一致，如果 x 是负数，那么余数也是负数
            int next = x % 10;
            //先判断如果把next处理是否已经越界
            if (outBound(res, next, positive)) {
                return 0;
            }
            //每次处理最后一位
            res = res * 10 + next;
            x = x / 10;
        }

        return res;
    }

    private static boolean outBound(int cur, int next, boolean positive) {
        //上下限与被除数一致
        int upBound = Integer.MAX_VALUE % 10; // 7
        int lowBound = Integer.MIN_VALUE % 10; // -8
        //如果是正数，那么cur如果等于 MAX / 10 ,则next必须必upBound小，否则超出范围
        if (positive) {
            if(cur > Integer.MAX_VALUE / 10) return true;
            if(cur == Integer.MAX_VALUE / 10)
                return next > upBound;
        //如果是负数，那么cur如果等于MIN / 10，那么next必须必
        } else{
            //譬如MIN是-88  /10就是-8
            //但是现在cur已经是-9，再多加以为就越界
            if(cur < Integer.MIN_VALUE / 10) return true;
            //lowBound是-8，那么要next要 < -8，比如-7，-6等
            if(cur == Integer.MIN_VALUE / 10)
                return next < lowBound;
        }
        return false;
    }

    public static void main(String[] args) {
        System.out.println(reverse(123));
    }


}
